home *** CD-ROM | disk | FTP | other *** search
/ Ian & Stuart's Australian Mac: Not for Sale / Another.not.for.sale (Australia).iso / hold me in your arms / PGP 2.6 / rsaref Toolkit / source / md2c.c < prev    next >
C/C++ Source or Header  |  1992-02-29  |  7KB  |  211 lines

  1. /* MD2C.C - RSA Data Security, Inc., MD2 message-digest algorithm
  2.  */
  3.  
  4. /* Copyright (C) 1990, RSA Data Security, Inc. All rights reserved.
  5.  
  6.    License to copy and use this software is granted for
  7.    non-commercial Internet Privacy-Enhanced Mail provided that it is
  8.    identified as the "RSA Data Security, Inc. MD2 Message Digest
  9.    Algorithm" in all material mentioning or referencing this software
  10.    or this function.
  11.  
  12.    RSA Data Security, Inc. makes no representations concerning either
  13.    the merchantability of this software or the suitability of this
  14.    software for any particular purpose. It is provided "as is"
  15.    without express or implied warranty of any kind.
  16.  
  17.    These notices must be retained in any copies of any part of this
  18.    documentation and/or software.  
  19.  */
  20.  
  21. #include "global.h"
  22. #include "md2.h"
  23.  
  24. static void MD2Transform PROTO_LIST
  25.   ((unsigned char [16], unsigned char [16], unsigned char [16]));
  26. static void MD2_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
  27. static void MD2_memset PROTO_LIST ((POINTER, int, unsigned int));
  28.  
  29. /* Permutation of 0..255 constructed from the digits of pi. It gives a
  30.    "random" nonlinear byte substitution operation.
  31.  */
  32. static unsigned char PI_SUBST[256] = {
  33.   41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
  34.   19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
  35.   76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
  36.   138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
  37.   245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
  38.   148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
  39.   39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
  40.   181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
  41.   150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
  42.   112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
  43.   96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
  44.   85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
  45.   234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
  46.   129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
  47.   8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
  48.   203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
  49.   166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
  50.   31, 26, 219, 153, 141, 51, 159, 17, 131, 20
  51. };
  52.  
  53. static unsigned char *PADDING[] = {
  54.   (unsigned char *)"", (unsigned char *)"\001", (unsigned char *)"\002\002",
  55.   (unsigned char *)"\003\003\003", (unsigned char *)"\004\004\004\004",
  56.   (unsigned char *)"\005\005\005\005\005",
  57.   (unsigned char *)"\006\006\006\006\006\006", 
  58.   (unsigned char *)"\007\007\007\007\007\007\007",
  59.   (unsigned char *)"\010\010\010\010\010\010\010\010",
  60.   (unsigned char *)"\011\011\011\011\011\011\011\011\011",
  61.   (unsigned char *)"\012\012\012\012\012\012\012\012\012\012",
  62.   (unsigned char *)"\013\013\013\013\013\013\013\013\013\013\013",
  63.   (unsigned char *)"\014\014\014\014\014\014\014\014\014\014\014\014",
  64.   (unsigned char *)"\015\015\015\015\015\015\015\015\015\015\015\015\015",
  65.   (unsigned char *)"\016\016\016\016\016\016\016\016\016\016\016\016\016\016",
  66.   (unsigned char *)
  67.     "\017\017\017\017\017\017\017\017\017\017\017\017\017\017\017",
  68.   (unsigned char *)
  69.     "\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020"
  70. };
  71.  
  72. /* MD2 initialization. Begins an MD2 operation, writing a new context.
  73.  */
  74. void MD2Init (context)
  75. MD2_CTX *context;                                                /* context */
  76. {
  77.   context->count = 0;
  78.   MD2_memset ((POINTER)context->state, 0, sizeof (context->state));
  79.   MD2_memset ((POINTER)context->checksum, 0, sizeof (context->checksum));
  80. }
  81.  
  82. /* MD2 block update operation. Continues an MD2 message-digest operation,
  83.    processing another message block, and updating the context.
  84.  */
  85. void MD2Update (context, input, inputLen)
  86. MD2_CTX *context;                                                /* context */
  87. unsigned char *input;                                        /* input block */
  88. unsigned int inputLen;                             /* length of input block */
  89. {
  90.   unsigned int i, index, partLen;
  91.   
  92.   /* Update number of bytes mod 16 */
  93.   index = context->count;
  94.   context->count = (index + inputLen) & 0xf;
  95.   
  96.   partLen = 16 - index;
  97.   
  98.   /* Transform as many times as possible.
  99.     */
  100.   if (inputLen >= partLen) {
  101.     MD2_memcpy ((POINTER)&context->buffer[index], (POINTER)input, partLen);
  102.     MD2Transform (context->state, context->checksum, context->buffer);
  103.  
  104.     for (i = partLen; i + 15 < inputLen; i += 16)
  105.       MD2Transform (context->state, context->checksum, &input[i]);
  106.     
  107.     index = 0;
  108.   }
  109.   else
  110.     i = 0;
  111.   
  112.   /* Buffer remaining input */
  113.   MD2_memcpy
  114.     ((POINTER)&context->buffer[index], (POINTER)&input[i], inputLen-i);
  115. }
  116.  
  117. /* MD2 finalization. Ends an MD2 message-digest operation, writing the
  118.      message digest and zeroizing the context.
  119.  */
  120. void MD2Final (digest, context)
  121. unsigned char digest[16];                                 /* message digest */
  122. MD2_CTX *context;                                                /* context */
  123. {
  124.   unsigned int index, padLen;
  125.  
  126.   /* Pad out to multiple of 16.
  127.    */
  128.   index = context->count;
  129.   padLen = 16 - index;
  130.   MD2Update (context, PADDING[padLen], padLen);
  131.  
  132.   /* Extend with checksum */
  133.   MD2Update (context, context->checksum, 16);
  134.   
  135.   /* Store state in digest */
  136.   MD2_memcpy ((POINTER)digest, (POINTER)context->state, 16);
  137.   
  138.   /* Zeroize sensitive information.
  139.    */
  140.   MD2_memset ((POINTER)context, 0, sizeof (*context));
  141. }
  142.  
  143. /* MD2 basic transformation. Transforms state and updates checksum
  144.      based on block.
  145.  */
  146. static void MD2Transform (state, checksum, block)
  147. unsigned char state[16];
  148. unsigned char checksum[16];
  149. unsigned char block[16];
  150. {
  151.   unsigned int i, j, t;
  152.   unsigned char x[48];
  153.   
  154.   /* Form encryption block from state, block, state ^ block.
  155.    */
  156.   for (i = 0; i < 16; i++) {
  157.     x[i] = state[i];
  158.     x[i+16] = block[i];
  159.     x[i+32] = state[i] ^ block[i];
  160.   }
  161.   
  162.   /* Encrypt block (18 rounds).
  163.    */
  164.   t = 0;
  165.   for (i = 0; i < 18; i++) {
  166.     for (j = 0; j < 48; j++)
  167.       t = x[j] ^= PI_SUBST[t];
  168.     t = (t + i) & 0xff;
  169.   }
  170.     
  171.   /* Save new state */
  172.   for (i = 0; i < 16; i++)
  173.     state[i] = x[i];
  174.     
  175.   /* Update checksum.
  176.    */
  177.   t = checksum[15];
  178.   for (i = 0; i < 16; i++)
  179.     t = checksum[i] ^= PI_SUBST[block[i] ^ t];
  180.  
  181.   /* Zeroize sensitive information.
  182.    */
  183.   MD2_memset ((POINTER)x, 0, sizeof (x));
  184. }
  185.  
  186. /* Note: Replace "for loop" with standard memcpy if possible.
  187.  */
  188. static void MD2_memcpy (output, input, len)
  189. POINTER output;
  190. POINTER input;
  191. unsigned int len;
  192. {
  193.   unsigned int i;
  194.   
  195.   for (i = 0; i < len; i++)
  196.     output[i] = input[i];
  197. }
  198.  
  199. /* Note: Replace "for loop" with standard memset if possible.
  200.  */
  201. static void MD2_memset (output, value, len)
  202. POINTER output;
  203. int value;
  204. unsigned int len;
  205. {
  206.   unsigned int i;
  207.   
  208.   for (i = 0; i < len; i++)
  209.     ((char *)output)[i] = (char)value;
  210. }
  211.